0

I have a ListView whose rows comprise of some TextViews and a button. Upon a user pressing the button, I want to remove that parent that houses the button from the ListView. How do I access my custom ArrayAdapter's fields from within a nested method (onClickListener) though? All I have to work with is the View v. Am I suppose to call v.getParent() multiple times, or is there a better way to do it?

  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
     ViewHolder holder = null;
     Action item = this.getItem(position);
     if (convertView == null) {
        convertView = inflater.inflate(R.layout.action_holder_layout,
              parent, false);
        holder = new ViewHolder();
        holder.title = (TextView) convertView
              .findViewById(R.id.action_holder_title);
        holder.finishBtn = (Button) convertView
              .findViewById(R.id.finish_action_button);
        convertView.setTag(holder);
     } else
        holder = (ViewHolder) convertView.getTag();
     holder.title.setText(item.getActionName());
     holder.finishBtn.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
           //REMOVE THE ACTION FROM THE ADAPTER'S ARRAYLIST
        }
     });
     return convertView;
  }

  static class ViewHolder {

     private TextView title;
     private Button finishBtn;
  }

2 Answers 2

1

Make item final:

final Action item = this.getItem(position);

and you can access it from onClick. Not a beautiful solution IMO, but will work:

remove(item);
Sign up to request clarification or add additional context in comments.

9 Comments

It does indeed work, but what do you mean by it not being the most elegant solution? Is there something better? This seems to be the most simplistic way.
@TonyN.Tran I don't like creating View.OnClickListener every time getView is called. I do it like this. It's a bit more robust.
Okay, going with your preferred method, what do I implement in my custom onClickListener? If the button is pressed, View v (the button) is passed. Instead of declaring any variables as final, how would I figure out which ListView row the button was clicked from?
Oh wait! Perhaps I could store a tag in the button, and retrieve it later from my custom onClick! Does that sound viable?
@TonyN.Tran Using setTag to store item is basically the same as using final. These are ok solutions that have no real drawbacks. It's just me not liking to use new in certain places in code (getView, onDraw, onTouchEvent), because they may be called often and cause Garbage Collections. Using convertView and holder pattern is enough. You may ignore my remarks ;)
|
1

If you need access to your ListView (and consequently its Adapter), a better way than using getParent().getParent()... would be to use the setTag() method on your View. Since you are already using it to insert a ViewHolder as a Tag of your view, why not add another field

ListView parentListView;

to your ViewHolder and retrieve it later in the onClick?

You could also set the ListView directly as a tag on your button.

You could also just access the adapter or other methods and fields directly from your onClick code since you're using an anonymous class.

4 Comments

Do you think you can explain to me what exactly ARE tags? I can understand setting IDs integers as "tags", but I don't quite get the setTag and getTag methods for ListViews. I kind of just followed from a template and understand everything BUT the tags. Why am I passing an object in setTag()? And what am I retrieving with getTag()?
Setting a tag on a view is just a convenient way to store arbitrary data in a view. You can store any Object using setTag and retrieve the same Object later. The tags don't DO anything, they are for you to use as you need them
Oh. So they're not not for searching by tag or anything? That seemed to be the most intuitive thing to do with "tags". Thanks for the explanation though! Now I just need to figure out what exactly I can do with such a thing.
well, searching is one of things you can do (I actually forgot about that) but they're not there just for searching. you can use them for whatever purpose you need

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.