C.Nego
C.Nego

Reputation: 11

RecyclerView get View by position

I have a RecyclerView and each CardView contains a TextView and an ImageView. Whenever I click an item, I want to set the image visibility to VISIBLE and to set the previous clicked item image's visibility to INVISIBLE.

This is my Adapter class :

public class CategoryAdapter extends RecyclerView.Adapter<CategoryAdapter.ViewHolder>{
private Context context;
private List<Category> lista;
private LayoutInflater layoutInflater;
private IncomeCategoryActivity activity;

private static final int CATEGORY_REQUEST=6;
private static final int ITEM_EDIT=1;
private static final int ITEM_DELETE=2;
private static final int EDIT_REQUEST=7;

private int current_pos=-1;


public CategoryAdapter(List<Category> lista, Context context, IncomeCategoryActivity activity) {
    this.context = context;
    this.lista = lista;
    this.activity=activity;
    layoutInflater=LayoutInflater.from(context);
}

@Override
public CategoryAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view=layoutInflater.inflate(R.layout.category_layout, parent, false);
    ViewHolder viewHolder=new ViewHolder(view, activity);

    return viewHolder;
}

@Override
public void onBindViewHolder(CategoryAdapter.ViewHolder holder, int position) {
    holder.imageView.setImageURI(lista.get(position).getUri());
    holder.textView.setText(lista.get(position).getCategory());
    holder.position = position;
    holder.category=lista.get(position);

    if(holder.category.isChecked()==true){
        holder.imageViewCheck.setVisibility(View.VISIBLE);
        current_pos=position;
    } else {
        holder.imageViewCheck.setVisibility(View.INVISIBLE);
    }
}

@Override
public int getItemCount() {
    return lista.size();
}

public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnCreateContextMenuListener, MenuItem.OnMenuItemClickListener{
    public ImageView imageView;
    public TextView textView;
    public ImageView imageViewCheck;
    public int position;
    public Category category;
    public IncomeCategoryActivity activity;

    public ViewHolder(View itemView, IncomeCategoryActivity activity) {
        super(itemView);
        this.activity=activity;

        imageView=itemView.findViewById(R.id.customCategoryImageView);
        textView=itemView.findViewById(R.id.customCategoryTextView);
        imageViewCheck=itemView.findViewById(R.id.customCheckImageView);

        itemView.setOnClickListener(this);
        itemView.setOnCreateContextMenuListener(this);

    }

    @Override
    public void onClick(View v) {
        String aux=textView.getText().toString();
        if(aux=="CATEGORIE NOUĂ"){
            Intent intent=new Intent(context, CustomIncomeActivity.class);
            activity.startActivityForResult(intent, CATEGORY_REQUEST);
        }
        else{
            imageViewCheck.setVisibility(View.VISIBLE);
            int pozitie_check=getLayoutPosition();
            Intent intent=new Intent(context, AddIncomeActivity.class);
            intent.putExtra("categorie_venit", aux);
            intent.putExtra("position_check", pozitie_check);
            activity.setResult(Activity.RESULT_OK, intent);
            activity.finish();
        }

    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        menu.setHeaderTitle("Selectează acțiunea");
        MenuItem edit=menu.add(0, ITEM_EDIT, 0, "Modifică");
        MenuItem delete=menu.add(0, ITEM_DELETE, 0, "Șterge");

        edit.setOnMenuItemClickListener(this);
        delete.setOnMenuItemClickListener(this);
    }

    @Override
    public boolean onMenuItemClick(MenuItem item) {
        int position=getLayoutPosition();
        if (item.getGroupId() == 0) {
            if(item.getItemId()==ITEM_EDIT){
                Category category=lista.get(position);
                Intent intent=new Intent(activity, CustomIncomeActivity.class);
                intent.putExtra("edit_icon", category.getUri());
                intent.putExtra("edit_category", category.getCategory());
                intent.putExtra("list_position", position);
                activity.startActivityForResult(intent, EDIT_REQUEST);
            }
            else if(item.getItemId()==ITEM_DELETE){
                lista.remove(position);
                notifyDataSetChanged();
            }
    }
    return true;

}

At this moment, whenever I click an item, there are two images VISIBLE on the RecyclerView: the clicked item's image and the previous clicked item's image. I think I need to get the previous View by its position and to manually set the visibility to INVISIBLE.

Upvotes: 1

Views: 14047

Answers (4)

Geet Thakur
Geet Thakur

Reputation: 2056

recycleView.getChildCount() and recycleView_parent.getChildAt() only gives the Adapter items which is shows only screen . that means if your list has 200 items and the only 5 items shows on screen so we can find only 5 item with the help of recycleView

i am using one simple trick to solve the issue.

  1. You can define Hashmap which hold your holder objects

     public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
         ArrayList<Model> dataList;
         Context context;
         HashMap<Integer,ViewHolder> holderlist;
    
    
     public MyAdapter(ArrayList<Model> dataList, Context context) {
         this.context = context;
         this.dataList = dataList;
         holderlist = new HashMap<>();
     }
    
  2. And after that to save the holder in Hashmap

     public void onBindViewHolder(final ViewHolder holder, final int position) {
         if(!holderlist.containsKey(position)){
             holderlist.put(position,holder);
         }
    
  3. Create a method in Adapter.

    public MyListAdapter.ViewHolder getViewByPosition(int position) {
             return holderlist.get(position);
         }
    
  4. Call this method from your Activity or whenever you want.

     for (int i = 0; i < datalList.size(); i++) {
                 MyAdapter.ViewHolder holder = ((MyAdapter)recycleView.getAdapter()).getViewByPosition(i);
                 View view = holder.itemView;
                 TextView tv = view.findViewById(R.id.tv);
    
     }
    

Upvotes: 11

user4571931
user4571931

Reputation:

Try this code.. add this code into adapter class for handling click event..

 OnItemClick onItemClick;

public void setOnItemClick(OnItemClick onItemClick) {
    this.onItemClick = onItemClick;
}

public interface OnItemClick {
    void getPosition(String data); //pass any data to shared it.
}

after bind method..

@Override
public void onBindViewHolder(final ItemViewHolder holder, final int position) {
    // below code handle click event on recycler view item.
    final String str=mStringList.get(position); //  here your boject
    if(holder.category.isChecked()==true){
        holder.imageViewCheck.setVisibility(View.VISIBLE);
        current_pos=position;
    } else {
        holder.imageViewCheck.setVisibility(View.INVISIBLE);
    }
    holder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            onItemClick.getPosition(str); // pass your data.
        }
    });
}

after bind adapter into recycler view it means adapter not null then called below code..

        adpater.setOnItemClick(new RecyclerViewAdpater.OnItemClick() {
        @Override
        public void getPosition(String data) {
            // hear update your value for check into if condition.
            data="sdfsdf";

            adpater.notifyDataSetChanged();
        }
    });

and also read comments and also try to make custon class and access that object value and update after click it.. this code only how to handle click event into recycler view.

Upvotes: 0

tahsinRupam
tahsinRupam

Reputation: 6405

You can do as following:

1) Declare a global variable:

private int selectedPos = -100;  // Put any irrelevant number you want

2) Set selected position onClick() :

@Override
public void onClick(View v) {
    selectedPos = getAdapterPosition();
}

3) Check selected postion and assign visibility inside onBindViewHolder():

@Override
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, int position) {

    if(position == selectedPos){
        holder.imageViewCheck.setVisibility(View.VISIBLE);
    } else {
        holder.imageViewCheck.setVisibility(View.INVISIBLE);
    }     
}

Upvotes: 1

Jay Thummar
Jay Thummar

Reputation: 2299

I have created the demo you can refer it and implement for single selection

 recyclerView.setAdapter(new RecyclerView.Adapter() {
        int selected_position = -1;

        @NonNull
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            return new RecyclerView.ViewHolder(LayoutInflater.from(parent.getContext()).inflate(
                    R.layout.row_color_list,parent,false)) {
                @Override
                public String toString() {
                    return super.toString();
                }
            };
        }

        @Override
        public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, int position) {
            ImageView imageView = holder.itemView.findViewById(R.id.image);

            if(selected_position == position){
                imageView.setVisibility(View.VISIBLE);
            }else {
                imageView.setVisibility(View.GONE);
            }

            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(selected_position != holder.getAdapterPosition()){
                        selected_position = holder.getAdapterPosition();
                        notifyDataSetChanged();
                    }
                }
            });

        }

        @Override
        public int getItemCount() {
            return 20;
        }
    });

Upvotes: 1

Related Questions