1

When a button is clicked, I'm trying to delete the row. At the very bottom, I call the delete method that I made. However it gives me an error (in the question). I tried making the delete method static, tried everything that android suggested

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

private List<numbers> mNumbers;

public myAdapter (List<numbers> numbers) {
    mNumbers = numbers;
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    View v  = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_slot, parent, false);
    ViewHolder vh = new ViewHolder(v);
    return vh;
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    holder.bindNumbers(mNumbers.get(position));
}

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

public void delete(int position) {
    mNumbers.remove(position);
    notifyItemRemoved(position);
}

public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

    TextView numberText;
    EditText checklistText;
    Button deleteButton;
    CheckBox checkDisBox;

    public ViewHolder(View itemView) {
        super(itemView);
        numberText = (TextView) itemView.findViewById(R.id.number);
        checklistText = (EditText) itemView.findViewById(R.id.editText);
        deleteButton = (Button) itemView.findViewById(R.id.deleteButton);
        checkDisBox = (CheckBox) itemView.findViewById(R.id.checkBox);

        deleteButton.setOnClickListener(this);
    }

    public void bindNumbers(numbers numbers) {
        numberText.setText(numbers.getInt() + "");
    }

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

EDITED PROBLEM BELOW

    @Override
public void onBindViewHolder(ViewHolder holder, int position) {
    holder.bindNumbers(mNumbers.get(position));
    holder.deleteButton.setOnClickListener(this);
}


public void delete(int position) {
    mNumbers.remove(position);
    notifyItemRemoved(position);
}

@Override
public void onClick(View v) {
    delete(getAdapterPosition());
}
Sheila Grant
  • 65
  • 1
  • 8
  • Possible duplicate of [non-static variable cannot be referenced from a static context](http://stackoverflow.com/questions/2559527/non-static-variable-cannot-be-referenced-from-a-static-context) – John3136 Nov 11 '15 at 03:10
  • already looked through that. didnt solve my problem at all – Sheila Grant Nov 11 '15 at 03:12
  • 1
    **Do not** setup the content of your views (this includes listeners) in the `ViewHolder` class. Do so from inside the adapter. – Breavyn Nov 11 '15 at 03:14
  • can you elaborate on that? ive been learning on teamtreehouse and this is pretty much what the teacher taught me in terms of how to use recyclerview – Sheila Grant Nov 11 '15 at 03:17
  • i tried putting an onclick listener in the Bind method but now its telling me that there is no such method as getAdapterPosition() – Sheila Grant Nov 11 '15 at 03:21
  • how about `holder.deleteButton.setTag(position)` then in `onClick(v)` get the tag and cast it to `int` like `Integer.valueOf(v.getTag().toString())`. – NamNH Nov 11 '15 at 03:32
  • I disagree with @Colin. You want to create your listener once, when the ViewHolder is created, rather than creating a new one each time it is bound. The only issue you're having is that your ViewHolder class is static but you're trying to access an outer class method. Remove the `static` keyword from your ViewHolder class and you should be fine. – RussHWolf Nov 11 '15 at 04:17
  • @Brucelet how is my new solution? – Breavyn Nov 11 '15 at 05:35
  • @Colin That's usually how I do things. – RussHWolf Nov 11 '15 at 14:07
  • Hearing @Brucelet say to remove the static keyword made me confused. Ive always been led to believe that the viewholder class must *always* be static. all the youtube videos, all the online sources, everything had that static keyword so i thought it was a must. but then just now i searched online and its not even needed! and it's better off to not use the static keyword. As a result i did something a bit different than Colin which to me looks easier. i posted my solution below so im wondering if my way would always work or if Colin's way is better. Thank you for your help!! – Sheila Grant Nov 12 '15 at 01:57
  • It's mostly a style thing. Removing static was the quickest way to make your code work, but I usually actually do something closer to @Colin's second solution in real code. It keeps the Adapter and the ViewHolder more independent from each other which usually makes the code easier to maintain over the long term. – RussHWolf Nov 12 '15 at 02:34
  • @SheilaGrant static inner classes perform better (slightly) and are less likely to cause memory leaks. They are heavily used in android for this reason and especially so in view holder pattern as its purpose is to increase performance. – Breavyn Nov 12 '15 at 02:58
  • I see. So your editted solution below would be the best way to approach this sort of situation? And why did you create an interface. Was that really needed? – Sheila Grant Nov 12 '15 at 03:01
  • @SheilaGrant an interface isn't strictly required, you could instead use the class `myAdapter` itself. Its just a design choice. – Breavyn Nov 12 '15 at 03:31

2 Answers2

2

Edit

I just went and implemented this myself, and this is what worked for me.

Create an interface for deleting items

public interface DeleteItem {
    void delete(int position);
}

Make your adapter implement this interface

public class myAdapter
    extends RecyclerView.Adapter<myAdapter.ViewHolder>
    implements DeleteItem {

    @Override
    public void delete(int position) {
        mNumbers.remove(position);
        notifyItemRemoved(position);
    }
}

Set your viewholder to take a reference to the interface

DeleteItem mDeleteItem;

public ViewHolder(View itemView, DeleteItem deleteItem) {
    super(itemView);
    mDeleteItem = deleteItem;
    ...        
}

Modify your view holders on click handler

@Override
public void onClick(View v) {
    mDeleteItem.delete(getAdapterPosition());
}

Finally when creating your view holder pass it the reference

ViewHolder vh = new ViewHolder(v, this);

Original Answer

A ViewHolder is to save your application from having to find the views inside of list items. It should only contain the myview = itemView.findViewById() type calls and nothing else.

The bindViewHolder() method should contain all the code that uses those views you found in the view holder.

@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
    holder.bindNumbers(mNumbers.get(position));
    // add listener here
    holder.deleteButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            delete(position);
        }
    }
}
Breavyn
  • 2,232
  • 16
  • 29
  • @SheilaGrant you do not need to use that method at all, follow the example implementation in my edit – Breavyn Nov 11 '15 at 03:31
  • Yep I did what you wrote and its sort of working. Im wondering why when I click the delete button, the row below gets deleted or just a random row at the bottom gets deleted or sometimes the row doesn't get deleted at all. The first time i open the app and delete a row it works fine but from the second time, it doesnt work anymore – Sheila Grant Nov 11 '15 at 03:36
0

Code hasnt really changed from my question but removing the static keyword really got rid of a lot of my struggles

public class ViewHolder extends RecyclerView.ViewHolder implements     View.OnClickListener{

    TextView numberText;
    EditText checklistText;
    Button deleteButton;
    CheckBox checkDisBox;

    public ViewHolder(View itemView) {
        super(itemView);
        numberText = (TextView) itemView.findViewById(R.id.number);
        checklistText = (EditText) itemView.findViewById(R.id.editText);
        deleteButton = (Button) itemView.findViewById(R.id.deleteButton);
        checkDisBox = (CheckBox) itemView.findViewById(R.id.checkBox);

        deleteButton.setOnClickListener(this);
    }

    public void bindNumbers(numbers numbers) {
        numberText.setText(numbers.getInt() + "");
    }

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

my delete method

public void delete(int position) {
    mNumbers.remove(position);
    notifyItemRemoved(position);
}
Sheila Grant
  • 65
  • 1
  • 8