简体   繁体   中英

Adding new button and spinner for each button click

In the activity when user click on add client button I want to add new view to the screen which contains a spinner with list of client names retrieved from api and a button that will do some action on click.

So I thought I would use a recycleview and adapter for this but I think I'm wrong

in the activity I have the adapter

private ClientAdapter clientAdapter;

When I retrieve clients name from API I set the adapter as

   clientRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
   clientAdapter= new clientAdapter(clientList , this , this);
   clientRecyclerView.setAdapter(podAdapter);

At this point I don't want the recycle view to render anything until user click on add new client button then I want to display one item that has spinner with client names and a button. Then if he clicks again on add client button I want to show another spinner and button and so on.

However now I'm having 3 clients so recycleview render 3 view items which make sense. But what the trick that I should do to achieve my goal?

在此处输入图像描述

Here's my adapter

public class ClintsAdapter extends RecyclerView.Adapter<ClintsAdapter.ViewHolder> {

    private List<Clients> clientsList;
    private EventListener listener;


    public ClintsAdapter(List<Clients> clientsList, EventListener listener , Context context) {
        this.clientsList = clientsList;
        this.EventListener = listener;
    }

    @NonNull
    @Override // To inflate view
    public ClintsAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.listitem_client, parent, false);
        ViewHolder viewHolder = new ViewHolder(view, listener);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull ClintsAdapter.ViewHolder holder, int position) {
        ClintsAdapter = new ArrayAdapter<Client>(context, R.layout.spinner_text_view, clientsList);
        ClintsAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        holder.clientSpinner.setAdapter(ClintsAdapter);
        holder.clientSpinner.setTitle("Choose client");
    }

    @Override
    public int getItemCount() {
        if (clientsList == null)
            return 0;
        return clientsList.size();
    }

    public interface PODListener {
        void onClick(int position);
    }

    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        private SearchableSpinner clientSpinner , collectMethodSpinner;

        EventListener listener;

        public ViewHolder(View itemView, final EventListener listener) {
            super(itemView);
            this.listener = podListener;
            clientSpinner = itemView.findViewById(R.id.spinner_client);
            btnComment = itemView.findViewById(R.id.btn_comment);

            btnComment.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if ( listener != null ) {
                        int position = getAdapterPosition();
                        if (position != RecyclerView.NO_POSITION){
                            listener.onClick(position);
                        }
                    }

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

and here's my list item

From comments:

The problem is I'm passing list of clients to the adapter (size of 3) then the adapter render 3 items. I don't want this behavior I want to have 0 item if user click on add I will render one item and so on

You are using a single ArrayList<Client> for two different purposes:

  1. The list of clients to choose from in the spinner
  2. The number of spinners to display in the RecyclerView.

These are two separate things, so you need two separate lists.

You can do that with just adding integer value for your ClientsAdapter . Set its default value as 0 and create a method for changing it's value. When you want to add new item (new Spinner and Button ) use that method and notify your adapter.

Add a new field called count for your ClientsAdapter .

private int count;    

Inside constructor assign its value to 0. So on start its value will be 0 and RecyclerView will show nothing.

public ClintsAdapter(List<Clients> clientsList, EventListener listener , Context context){
    this.clientsList = clientsList;
    this.EventListener = listener;
    count = 0;
}

Change getItemCount method's return value. According to your code getItemCount returns size of your List . That List is for Spinner and has no relation with this method. Instead of returning your List 's size return count .

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

Create a method for changing count 's value. count starts with 0 (assigned it 0 inside constructor) and when you click Button (add new Spinner and Button ) this method will change its value.

public void addItem(int count) {
    this.count = count;
}

Whenever you click Button simply call addItem method and pass new count value and notify your clientAdapter .

addClient.setOnClickListener(v -> {
    int count = clientRecyclerView.getChildCount();
    clientAdapter.addItem(count+1);
    clientAdapter.notifyItemInserted(count);
});

NOTE: I don't get it why you're setting podAdapter for RecyclerView .

clientRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
clientAdapter= new clientAdapter(clientList , this , this);
clientRecyclerView.setAdapter(podAdapter);

You're creating clientAdapter reference for your ClientsAdapter but while setting adapter for RecyclerView , you're using different reference ( podAdapter ).

Full code for ClientsAdapter :

public class ClintsAdapter extends RecyclerView.Adapter<ClintsAdapter.ViewHolder> {

    private List<Clients> clientsList;
    private EventListener listener;
    private int count;


    public ClintsAdapter(List<Clients> clientsList, EventListener listener , Context context) {
        this.clientsList = clientsList;
        this.EventListener = listener;
        count = 0;
    }

    @NonNull
    @Override // To inflate view
    public ClintsAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.listitem_client, parent, false);
        ViewHolder viewHolder = new ViewHolder(view, listener);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull ClintsAdapter.ViewHolder holder, int position) {
        ClintsAdapter = new ArrayAdapter<Client>(context, R.layout.spinner_text_view, clientsList);
        ClintsAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        holder.clientSpinner.setAdapter(ClintsAdapter);
        holder.clientSpinner.setTitle("Choose client");
    }

    public void addItem(int count) {
        this.count = count;
    }    

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

    public interface PODListener {
        void onClick(int position);
    }

    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        private SearchableSpinner clientSpinner , collectMethodSpinner;

        EventListener listener;

        public ViewHolder(View itemView, final EventListener listener) {
            super(itemView);
            this.listener = podListener;
            clientSpinner = itemView.findViewById(R.id.spinner_client);
            btnComment = itemView.findViewById(R.id.btn_comment);

            btnComment.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if ( listener != null ) {
                        int position = getAdapterPosition();
                        if (position != RecyclerView.NO_POSITION){
                            listener.onClick(position);
                        }
                    }

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM