I have a horizontal RecyclerView that shows images for selection of a "profile" image.
I'm using CircleImageView to leave the images with rounded corners, this library makes it possible to place a border on each image.
Note a RecyclerViewItemLayout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/avatar_select"
android:paddingTop="5dp"
android:layout_width="80dp"
android:layout_height="80dp"
android:padding="5dp"
app:civ_border_color="#color/colorPrimary"
app:civ_border_width="3dp"
android:src="#drawable/avatar1"/>
</LinearLayout>
When an item is clicked, the CircleImageView border should match the color of the ColorAsset, and when a new item is clicked (as if the user changed his or her opinion about the "profile" photo and wanted another), the new item should receive the border and the old selection should return to ColorPrimary.
Note a RecyclerViewAdapter.java
public class AvatarAdapter extends RecyclerView.Adapter<AvatarAdapter.MyViewHolder> {
private Context mContext;
private List<Avatar> mdata;
public AvatarAdapter(Context mContext, List<Avatar> mdata) {
this.mContext = mContext;
this.mdata = mdata;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view;
LayoutInflater mInflater = LayoutInflater.from(mContext);
view = mInflater.inflate(R.layout.escolhe_avatar,parent,false);
final MyViewHolder vHolder = new MyViewHolder(view);
return vHolder;
}
#Override
public void onBindViewHolder(#NonNull final MyViewHolder holder, int position) {
holder.image.setImageResource(mdata.get(position).getImage());
holder.image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.image.setBorderColor(R.color.colorAccent);
}
});
}
});
}
#Override
public int getItemCount() {
return mdata.size();
}
public static class MyViewHolder extends RecyclerView.ViewHolder {
private CircleImageView image;
public MyViewHolder(View itemView){
super(itemView);
image = (CircleImageView) itemView.findViewById(R.id.avatar_select);
}
}
}
I already broke my head, I researched but I could not reach a solution, can anyone help me please?
Taking advantage of a logic from a previous answer, I thought that with each click, I should update all the items execto the one that receive the edge of ColorAccent.
Veja a minha classe onBindViewClass do meu RecyclerViewAdapter.class
#Override
public void onBindViewHolder(#NonNull final MyViewHolder holder, final int position) {
holder.image.setImageResource(mdata.get(position).getImage());
holder.image.setBorderColor(getColor(mContext, R.color.colorPrimary));
holder.image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.image.setBorderColor(getColor(mContext, R.color.colorAccent));
for (int i=0; i <= mdata.size(); i++){
if (i != position){
notifyItemChanged(i, null);
}
}
}
});
}
if i understood correctly what you want to do this should work
#Override
public void onBindViewHolder(#NonNull final MyViewHolder holder, int position) {
holder.image.setImageResource(mdata.get(position).getImage());
holder.image.setBorderColor(R.color.colorPrimary);
holder.image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
notifyDataSetChanged();
holder.image.setBorderColor(R.color.colorAccent);
}
});
}
});
}
Related
Now that I got my RecyclerView working, and I can communicate between my Activity and my Adapter, I wanted to create an OnClickListener, which I did with success.
But somehow, it only works on buttons, not on other items.
In the Layout of my RecyclerView, I am having the following:
<TextView
android:id="#+id/tvWebsite"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:singleLine="true"
android:text="tvWebsite" />
<Button
android:id="#+id/btnWebsite"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
So the TextView is clickable. The button is too, but that is default behaviour.
In my Adapter class, I am having the following:
public class CompanyAdapter extends RecyclerView.Adapter<CompanyAdapter.ViewHolder>
{
private Context mContext;
private ArrayList<Company> companyname;
public CompanyAdapter (Context context, ArrayList<Company> list)
{
this.mContext = context;
companyname = list;
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
{
TextView tvCompanyName;
TextView tvVatID;
TextView tvPostalCode;
TextView tvPhoneNumber;
TextView tvProprietorName;
TextView tvWebsite;
TextView tvEmail;
TextView tvFirstAvailableDate;
TextView tvFirstAvailableTimeBlock;
TextView tvAvailableInPostalCode;
TextView tvAvailableNumberOfPersons;
Button btnWebsite;
public ViewHolder(#NonNull final View itemView)
{
super(itemView);
tvCompanyName = itemView.findViewById(R.id.tvCompanyName);
tvVatID = itemView.findViewById(R.id.tvVatNo);
tvPostalCode = itemView.findViewById(R.id.tvPostalCode);
tvPhoneNumber = itemView.findViewById(R.id.tvPhoneNumber);
tvProprietorName = itemView.findViewById(R.id.tvProprietorName);
tvWebsite = itemView.findViewById(R.id.tvWebsite);
tvEmail = itemView.findViewById(R.id.tvEmail);
tvFirstAvailableDate = itemView.findViewById(R.id.tvFrstAvailableDate);
tvFirstAvailableTimeBlock = itemView.findViewById(R.id.tvFirstAvailableTimeBlock);
tvAvailableInPostalCode = itemView.findViewById(R.id.tvPostalCodeAvailable);
tvAvailableNumberOfPersons = itemView.findViewById(R.id.tvAvailableNumberOfPersons);
btnWebsite = itemView.findViewById(R.id.btnWebsite);
tvWebsite.setClickable(true);
tvWebsite.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view) {
if (mContext instanceof SearchForHelp) {
((SearchForHelp) mContext).ClickWebsite();
}
}
});
btnWebsite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (mContext instanceof SearchForHelp) {
((SearchForHelp) mContext).ClickButton();
}
}
});
}
#Override
public void onClick(View view) {
}
}
#NonNull
#Override
public CompanyAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_items, viewGroup, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull CompanyAdapter.ViewHolder viewHolder, int i) {
viewHolder.itemView.setTag(companyname.get(i));
viewHolder.tvCompanyName.setText(companyname.get(i).getStrCompanyName());
viewHolder.tvVatID.setText(companyname.get(i).getStrVatID());
viewHolder.tvPostalCode.setText(companyname.get(i).getStrPostalCode());
viewHolder.tvPhoneNumber.setText(companyname.get(i).getStrPhoneNumber());
viewHolder.tvProprietorName.setText(companyname.get(i).getStrProprietorName());
viewHolder.tvWebsite.setText(companyname.get(i).getStrWebsite());
viewHolder.tvEmail.setText(companyname.get(i).getStrEmail());
viewHolder.tvFirstAvailableDate.setText(companyname.get(i).getStrFirstAvailableDate());
viewHolder.tvFirstAvailableTimeBlock.setText(companyname.get(i).getStrFirstAvailableTimeBlock());
viewHolder.tvAvailableInPostalCode.setText(companyname.get(i).getStrAvailableInPostalCode());
viewHolder.tvAvailableNumberOfPersons.setText(companyname.get(i).getStrAvailableNumberOfPersons());
viewHolder.tvWebsite.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view) {
//Toast.makeText(getClass(),"Test",Toast.LENGTH_SHORT).show();
//viewHolder.tvCompanyName.setText("Changed");
}
});
}
#Override
public int getItemCount() {
return companyname.size();
}
}
And finally, in my Activity:
public void ClickButton()
{
Toast.makeText(getApplicationContext(),"Clicked on Button",Toast.LENGTH_LONG).show();
}
public void ClickWebsite()
{
Toast.makeText(getApplicationContext(),"Clicked on TextView",Toast.LENGTH_LONG).show();
}
Please note, that
tvWebsite.setClickable(true);
has been added to see if it made any difference, but it didn't.
If I click on the button, it toastes "Clicked on button", but if I click on the TextView, nothing happens.
So what do I miss in order to make the TextView tvWebsite clickable?
There is no need for tvWebsite.setClickable(true);
And you are setting click listener for tvWebsite in onBindViewHolder callback again.
You need to remove this code from onBindViewHolder method.
viewHolder.tvWebsite.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view) {
//Toast.makeText(getClass(),"Test",Toast.LENGTH_SHORT).show();
//viewHolder.tvCompanyName.setText("Changed");
}
});
---------rest is fine.
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"
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,
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
I'm taking pictures by camera, adding them to ArrayList as Bitmap. I have recyclerView that is showing taken images. I want to have an alertdialog, that shows clicked image with option to delete. I'm having a problem with setting custom layout to AlertDialog. When I click on image, app crashes and error says
java.lang.ClassCastException: android.support.v7.widget.AppCompatImageView cannot be cast to android.view.ViewGroup
Error point to this row of code
View viewInflated = LayoutInflater.from(view.getContext()).inflate(R.layout.dialog_image, (ViewGroup) view,false);
imageDialog.setView(viewInflated);
but I'm not sure what I should do. I tried to change (ViewGroup) to something else but with no luck.
Adapter.java
public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
private List<Bitmap> fotky;
private Bitmap foto;
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recycler_view_item, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder holder, final int position) {
foto = fotky.get(position);
holder.photo.setImageBitmap(foto);
holder.photo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
AlertDialog.Builder imageDialog = new AlertDialog.Builder(view.getContext());
imageDialog.setTitle("Image");
View viewInflated = LayoutInflater.from(view.getContext()).inflate(R.layout.dialog_image, (ViewGroup) view,false);
imageDialog.setView(viewInflated);
ImageView image = viewInflated.findViewById(R.id.fotka);
image.setImageBitmap(foto);
imageDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.cancel();
}
});
imageDialog.setNegativeButton("delete", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
remove(position);
}
});
imageDialog.show();
//TODO tady ukázat full image s možností smazání
//remove(position);
}
});
}
public void add(int position, Bitmap item) {
fotky.add(position, item);
notifyItemInserted(position);
}
public void remove(int position) {
fotky.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, fotky.size());
}
public Adapter(List<Bitmap> myDataset) {
fotky = myDataset;
}
#Override
public int getItemCount() {
return fotky.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public ImageView photo;
public ViewHolder(View itemView) {
super(itemView);
photo = itemView.findViewById(R.id.imageView);
}
}
}
Dialog_image.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/fotka"
android:contentDescription="photo"/>
</LinearLayout>
Reason behind this crash is you have setup click listener on holder.photo which is of type AppCompatImageView. inside onClick block you are typecasting it to ViewGroup.
Change it to following.
View viewInflated = LayoutInflater.from(view.getContext()).inflate(R.layout.dialog_image, null);
It should work.