skip to Main Content

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


  1. assuming you want to trigger callback when imageView is clicked, after this line: imageView=itemView.findViewById(R.id.ItemImageView);
    add this:

     imageView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //startActivity(intent);
        }
    });
    
    Login or Signup to reply.
  2. I don’t see this very often but you could have LiveData object inside the Adapter that the Fragment observes.

    Then you can have "commands" that are paired with the Item received.

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({
       ImageCommand.DELETE,
       ImageCommand.UPDATE,
       ImageCommand.DETAILS,
       ImageCommand.IMAGE,
    })
    public @interface ImageCommand {
        int DELETE = 1;
        int UPDATE = 2;
        int DETAILS = 3;
        int IMAGE = 4;
    }
    

    Inside the adapter

    public MutableLiveData<Pair<Integer,Item>> commandPair = new MutableLiveData<>();
    
    //When you need to delete the image
    
    commandPair.setValue(new Pair<Integer,Item>(ImageCommand.DELETE,mItems.get(position)))
    
    //When you need to update the image
    
    commandPair.setValue(new Pair<Integer,Item>(ImageCommand.UPDATE ,mItems.get(position)))
    
    //When you need to do something when the details is clicked
    
    commandPair.setValue(new Pair<Integer,Item>(ImageCommand.DETAILS,mItems.get(position)))
    
    //When you need to do something when the image is clicked
    
    commandPair.setValue(new Pair<Integer,Item>(ImageCommand.IMAGE,mItems.get(position)))
    

    Inside the Fragment/Activity

       adapter.commandPair.observe(getLifecycleOwner(),(command)->{
              if(command == null)
                    return;
              switch(command.first){
                  case ImageCommand.DELETE:
                       //Delete the image
                       //-> Image is here command.second;
                       break;
                  case ImageCommand.UPDATE:
                       //Update the image
                       //-> Image is here command.second;
                       break;
                  case ImageCommand.DETAILS:
                       //User click the image details.
                       //-> Image is here command.second;
                       break;
                  case ImageCommand.IMAGE:
                       //User click the image itself.
                       //-> Image is here command.second;
                       break;
              }
           
       });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search