I have a RecyclerView in my app that shows a list of items,
right now i can click on the whole item (image + detalis beside) and open it in a new activity.
I’m trying to implement other case instead – I want only the image to be "clickable"and not the whole item.
this is my ItemsActivity class which implements my adapter (next class):
public class ItemsActivity extends AppCompatActivity implements ImageAdapter.OnItemClickListener {
private int mDate, mMonth, mYear;
Date date2;
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd",java.util.Locale.getDefault());
private RecyclerView mRecyclerView;
private ImageAdapter mAdapter;
private FirebaseStorage mStorage;
private DatabaseReference mDatabaseRef;
private ValueEventListener mDBListener;
private List<Item> mItem;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_items);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mRecyclerView=findViewById(R.id.mRecyclerView);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mItem=new ArrayList<>();
mAdapter=new ImageAdapter(ItemsActivity.this,mItem);
mRecyclerView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(ItemsActivity.this);
mStorage=FirebaseStorage.getInstance();
mDatabaseRef= FirebaseDatabase.getInstance().getReference("Item");
mDBListener = mDatabaseRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
mItem.clear();
for(DataSnapshot postSnapshot: snapshot.getChildren()){
Item item = postSnapshot.getValue(Item.class);
item.setKey(postSnapshot.getKey());
mItem.add(item);
}
mAdapter.notifyDataSetChanged();
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
Toast.makeText(ItemsActivity.this, error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void onItemClick(int position) {
Intent fullScreenIntent = new Intent(this,FullScreenActivity.class);
Item selecteditem=mItem.get(position);
if(selecteditem.getUri()!=null){
fullScreenIntent.setData(Uri.parse(selecteditem.getUri()));
startActivity(fullScreenIntent);
}
else{
Toast.makeText(ItemsActivity.this,"אין תמונה להצגה",Toast.LENGTH_SHORT).show();
}
}
@Override
public void onDeleteClick(int position){
Item selectedItem=mItem.get(position);
String selectedKey= selectedItem.getKey();
StorageReference imageref;
if(selectedItem.getUri()!=null){
imageref=mStorage.getReferenceFromUrl(selectedItem.getUri());
imageref.delete().addOnSuccessListener(aVoid -> {
mDatabaseRef.child(selectedKey).removeValue();
Toast.makeText(ItemsActivity.this, "פריט נמחק", Toast.LENGTH_SHORT).show();
});
}
else{
Toast.makeText(ItemsActivity.this, "פריט נמחק", Toast.LENGTH_SHORT).show();
mDatabaseRef.child(selectedKey).removeValue();
}
}
@Override
public void onUpdateClick(int position){
Item selecteditem=mItem.get(position);
final DialogPlus dialogPlus=DialogPlus.newDialog(ItemsActivity.this)
.setContentHolder(new ViewHolder(R.layout.dialogcontent))
.setExpanded(true,1300) // was 1200
.create();
View myview=dialogPlus.getHolderView();
EditText price=myview.findViewById(R.id.price);
EditText supp=myview.findViewById(R.id.usupplier);
EditText invoice=myview.findViewById(R.id.uinvoice);
EditText date=myview.findViewById(R.id.udatecreate);
EditText exgroup=myview.findViewById(R.id.uexpensegroup);
EditText extype=myview.findViewById(R.id.uexpensetype);
Button update=myview.findViewById(R.id.usubmit);
price.setText(String.valueOf(selecteditem.getPrice()));
supp.setText(selecteditem.getNameOfSupplier());
invoice.setText(selecteditem.getInvoiceNumber());
date.setText(selecteditem.getDateOfCreate());
date.setOnClickListener(view -> {
final Calendar Cal=Calendar.getInstance();
mDate=Cal.get(Calendar.DAY_OF_MONTH);
mMonth=Cal.get(Calendar.MONTH);
mYear=Cal.get(Calendar.YEAR);
DatePickerDialog datePickerDialog=new DatePickerDialog(ItemsActivity.this, (datePicker, year, month, dayOfMonth) -> {
Cal.set(year, month, dayOfMonth);
date.setText(simpleDateFormat.format(Cal.getTime()));
date2=Cal.getTime();
},mYear,mMonth,mDate);
datePickerDialog.getDatePicker().setMaxDate(System.currentTimeMillis()-1000);
datePickerDialog.show();
});
exgroup.setText(selecteditem.getExpenseGroup());
extype.setText(selecteditem.getExpenseType());
dialogPlus.show();
update.setOnClickListener(view -> {
Map<String,Object> map=new HashMap<>();
map.put("price",Double.parseDouble(price.getText().toString()));
map.put("nameOfSupplier",supp.getText().toString());
map.put("invoiceNumber",invoice.getText().toString());
map.put("dateOfCreate",date.getText().toString());
map.put("expenseGroup",exgroup.getText().toString());
map.put("expenseType",extype.getText().toString());
FirebaseDatabase.getInstance().getReference().child("Item")
.child(selecteditem.getKey()).updateChildren(map)
.addOnSuccessListener(unused -> dialogPlus.dismiss())
.addOnFailureListener(e -> dialogPlus.dismiss());
Toast.makeText(ItemsActivity.this, "נתוני פריט עודכנו", Toast.LENGTH_SHORT).show();
});
}
@Override
protected void onDestroy() {
super.onDestroy();
mDatabaseRef.removeEventListener(mDBListener);
}}
and this is my ImageAdapter class:
public class ImageAdapter extends RecyclerView.Adapter<ImageAdapter.ImageViewHolder> {
private Context mContext;
private List<Item> mItems;
private OnItemClickListener mListener;
public ImageAdapter(Context context, List<Item> items){
mContext=context;
mItems=items;
}
@NonNull
@Override
public ImageViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v= LayoutInflater.from(mContext).inflate(R.layout.row_item,parent,false);
return new ImageViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull ImageViewHolder holder, int position) {
Item current = mItems.get(position);
//holder.ViewDate.setText(changeDateFormat(current.getDateOfCreate()));
holder.ViewDate.setText(current.getDateOfCreate());
holder.ViewInvoice.setText(current.getInvoiceNumber());
holder.ViewPrice.setText("₪"+String.valueOf(current.getPrice()));
Glide.with(this.mContext)
.load(current.getUri())
.placeholder(R.drawable.unnamed)
.error(R.drawable.unnamed)
.fitCenter()
.centerCrop()
.into(holder.imageView);
}
@Override
public int getItemCount() {
return mItems.size();
}
public class ImageViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener,
View.OnCreateContextMenuListener, MenuItem.OnMenuItemClickListener {
public TextView ViewDate;
public TextView ViewInvoice;
public TextView ViewPrice;
public ImageView imageView;
public ImageViewHolder(@NonNull View itemView) {
super(itemView);
ViewDate = itemView.findViewById(R.id.DateTextView);
ViewPrice = itemView.findViewById(R.id.PriceTextView);
ViewInvoice=itemView.findViewById(R.id.InvoiceTextView);
imageView=itemView.findViewById(R.id.ItemImageView);
itemView.setOnClickListener(this);
itemView.setOnCreateContextMenuListener(this);
}
@Override
public void onClick(View view) {
if(mListener!=null){
int position=getAdapterPosition();
if(position!=RecyclerView.NO_POSITION){
mListener.onItemClick(position);
}
}
}
@Override
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo contextMenuInfo) {
menu.setHeaderTitle("בחר פעולה");
MenuItem delete=menu.add(Menu.NONE,1,1,"מחק");
MenuItem update=menu.add(Menu.NONE,2,2,"עדכן נתוני פריט");
delete.setOnMenuItemClickListener(this);
update.setOnMenuItemClickListener(this);
}
@Override
public boolean onMenuItemClick(MenuItem item) {
if(mListener!=null){
int position=getAdapterPosition();
if(position!=RecyclerView.NO_POSITION){
switch (item.getItemId()){
case 1:
mListener.onDeleteClick(position);
return true;
case 2:
mListener.onUpdateClick(position);
return true;
}
}
}
return false;
}
}
public interface OnItemClickListener{
void onItemClick(int position);
void onDeleteClick(int position);
void onUpdateClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener){
mListener=listener;
}}
Thanks!
2
Answers
assuming you want to trigger callback when imageView is clicked, after this line: imageView=itemView.findViewById(R.id.ItemImageView);
add this:
I don’t see this very often but you could have
LiveData
object inside theAdapter
that theFragment
observes.Then you can have "commands" that are paired with the
Item
received.Inside the adapter
Inside the Fragment/Activity