C. Skjerdal
C. Skjerdal

Reputation: 3108

Update Adapter/RecyclerView in custom TextWatcher

I am trying to add/delete an item in my RecyclerView from a custom TextWatcher.

Here is a piece of my Custom Text Watcher

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
    //get the position and size from edit text
    int position = (int) editText.getTag(R.string.position);
    int size = (int) editText.getTag(R.string.listSize);

    //if the character count equals 1
    if (count == 1){
        //check if the current position is proven to be the last item in the list
        if (position + 1 == size){
            //add an item to the list here

        }
    } 
}

Where it says "add an item to the adapter list here" I want to add an item to my recyclerview and update the adapter.

I am pretty sure there is no way to do this easily. Do I need to set this up with a Singleton design pattern, or is there a way I can create a custom listener on my MainActivity that is called when I want to add an item?

I am using a custom adapter as well that I can post if anyone needs.

**Update with my custom adapter

public class PlayerAdapter extends RecyclerView.Adapter<PlayerAdapter.PlayerHolder>{

    private List<Players> playerList;

    public PlayerAdapter(List<Players> list) {
        playerList = list;
    }

    /* ViewHolder for each item */
    public class PlayerHolder extends RecyclerView.ViewHolder  {

        EditText playerName;

        PlayerHolder(View itemView) {
            super(itemView);
            Log.e("Holder","setview");
            playerName = itemView.findViewById(R.id.name);
            MyTextWatcher textWatcher = new MyTextWatcher(playerName);
            playerName.addTextChangedListener(textWatcher);
        }
    }

    @Override
    public PlayerHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.new_player_item_layout, parent, false);
        return new PlayerHolder(itemView);
    }

    @Override
    public void onBindViewHolder(PlayerHolder holder, int position) {
        Players playerItem = playerList.get(position);

        //Sets Text
        //holder.playerName.setText(playerItem.getName());
        holder.playerName.setTag(R.string.listSize, playerList.size());
        holder.playerName.setTag(R.string.position, position);
    }

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

    public void updateList(List<Players> newList){
        playerList = newList;
        notifyDataSetChanged();
    }
}

Upvotes: 3

Views: 3638

Answers (1)

Jojo Narte
Jojo Narte

Reputation: 3104

EDIT: Add instead of Update What you would want is an interface to connect the logic for both the TextWatcher and the RecyclerView For example you could have this interface but you could modify it as you need.

interface AddPlayerInterface {
    private void addPlayer(Player player);
}

You can implement it in your Adapter for example

    class Adapter extends RecyclerView.Adapter implements AddPlayerInterface {
        // ... your other adapter implementation codes

        @override
        private void addPlayer(Player player) {
            // here you can add the new player to the list
            list.add(player);
            notifyDataSetChanged(); // or any of the helper methods to notify adapter of change like for specific rows
        }

    }

then you pass your listener reference into the textwatcher via

@Override
public PlayerHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View itemView = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.new_player_item_layout, parent, false);


    return new PlayerHolder(itemView, listener);
}

Your textwatcher would contain the reference to the interface to call class CustomWatcher implements TextWatcher { protected Player player; private AddPlayerInterface listener;

   private CustomWatcher(Player player, AddPlayerInterface interface)
   {
       this.player = player;
       this.listener = interface;
   }

   @Override
   public void afterTextChanged(Editable editable)
   {
        // if you want it on after textchanged you'd call it here and you would probably create the new player instance here
       Player player = new Player();
       listener.addPlayer(player); // this would call the listener implementation on your adapter 

   }
}

Upvotes: 2

Related Questions