0

Ok so I've searched around on SO for a bit but can't seem to get an answer to work. This one is close, but it removes the last item in the list and then crashes when I remove the last value. I just want to have a button from inside of the list row perform an action based on the content in the list, and then remove that row from the list. Thank you!

public class CitrusListAdapter extends ArrayAdapter<CitrusList>
{

//Globals
Context context;
int layoutResourceId;
ArrayList<CitrusList> data = null;

//Create the list item row
public CitrusListAdapter(Context context, int layoutResourceId, ArrayList<CitrusList> listItems)
{
    super(context, layoutResourceId, listItems);
    this.layoutResourceId = layoutResourceId;
    this.context = context;
    this.data = listItems;
}

//Expand and place items for List View onto calling page in ListView
@Override
public View getView(final int position, View convertView, ViewGroup parent)
{
    View row = convertView;
    CitrusListHolder holder = null;

    if(row == null)
    {
        LayoutInflater inflater = ( (Activity) context).getLayoutInflater();
        row = inflater.inflate(layoutResourceId, parent, false);
        holder = new CitrusListHolder();

        //holder.txtTitle = (TextView)row.findViewById(R.id.CitrusListTitle);
        holder.colorSpinner = (Spinner)row.findViewById(R.id.color_spinner);
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(getContext(),
                R.array.colors_array, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        holder.colorSpinner.setAdapter(adapter);

        holder.textureSpinner = (Spinner)row.findViewById(R.id.texture_spinner);
        ArrayAdapter<CharSequence> texture_adapter = ArrayAdapter.createFromResource(getContext(),
                R.array.texture_array, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        holder.textureSpinner.setAdapter(texture_adapter);

        holder.soliditySpinner = (Spinner)row.findViewById(R.id.solidity_spinner);
        ArrayAdapter<CharSequence> solidity_adapter = ArrayAdapter.createFromResource(getContext(),
                R.array.solidity_array, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        holder.soliditySpinner.setAdapter(solidity_adapter);

        Button rateButton = (Button) row.findViewById(R.id.rate_button);
        rateButton.setTag(position);
        rateButton.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                Integer index = (Integer) v.getTag();
                data.remove(index.intValue());
                notifyDataSetChanged();
            }
        });

        row.setTag(holder);
    }
    else
    {
        holder = (CitrusListHolder)row.getTag();
    }

    CitrusList SingleLine = data.get(position);
    //holder.txtTitle.setText(SingleLine.title);
    return row;
}

//Stores the values of the items in the list view
static class CitrusListHolder
{
    //TextView txtTitle;
    Spinner colorSpinner;
    Spinner textureSpinner;
    Spinner soliditySpinner;
}
}
2
  • how do you remove the data from array? Commented Feb 27, 2013 at 7:38
  • are you setting Integer as Tag to Button? Commented Feb 27, 2013 at 7:42

4 Answers 4

5

you can remove the item from the array list by using remove() method and then call the notifyDataSetChanged() method of adapter.

Sign up to request clarification or add additional context in comments.

3 Comments

OP has removed the item and called the notifyDataSetChanged() from onClick() of the Button
I'm not sure how what you're saying is different from what I have in my code. Can you elaborate?
For anyone else looking for this. I wrote a custom adapter for a layout that looks like stackoverflow.com/questions/26373402/… and had a similar issue. In my listener, after the asynchronous call to delete returned successfully, I just used the following code comments.remove (position); and then notifyDataSetChanged ();. My listener, was implemented right in the getView () in my custom adapter and in my design, comments is the ListView loaded as ArrayList<HashMap<String, String>> into my BaseAdapter subclass.
2

I think you should try this

rateButton.setOnClickListener(new OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            int index = Integer.parseInt(v.getTag().toString())
            data.remove(index);
            notifyDataSetChanged();
        }
    });

2 Comments

Nope same issue with this set. Thank you though.
@ Jignesh Ansodariya +1 it works for me thank you (We have to set position as tag while adding component in getView method)
1

To remove a row from a ListView, You modify the data held by the Adapter that is controlling the ListView. If the adapter is an ArrayAdapter, call remove() on the ArrayAdapter and give it the position of whatever item you need to be deleted. Then notify the adapter using notifyDataSetChanged(). The adapter will refresh the ListView and your offending row will be deleted.

In your code, you're not storing the position of the current item in your view holder. Change it to this:

static class CitrusListHolder
{
    //TextView txtTitle;
    Spinner colorSpinner;
    Spinner textureSpinner;
    Spinner soliditySpinner;
    int currentPosition;
}

Then set the position in the holder

Button rateButton = (Button) row.findViewById(R.id.rate_button);
        rateButton.setTag(position); //delete this line
        holder.currentPosition = position; //storing current position in holder
        rateButton.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                CitrusListHolder currHolder = (CitrusListHolder) v.getParent().getTag(); //get button's parent which is the row
                data.remove(currHolder.currentPosition);  //get the stored position and remove the corresponding row
                notifyDataSetChanged();
            }
        });

That should work.

7 Comments

Hrm. I added currentPosition to the holder, removed the rateButton.setTag line, set currentPosition = position, and tried index.currentPosition within onClick, but I'm getting "currentPosition cannot be resolved or is not a field." When I used holder.currentPosition (I made holder global), it does the same thing of only removing the last row in the list rather than the selected item.
I've edited the answer. You need to get the tag as a CitrusListHolder and not an integer. Set the holder back to it's non global state as well.
OK so I have this: CitrusListHolder currHolder = (CitrusListHolder) v.getTag(); data.remove(currHolder.currentPosition); and it's crashing with a null pointer exception. Even if I just throw currholder.currentPosition into a toast, it crashes on the second line there.
You are still setting the tag to the row right? row.setTag(holder);
Yes: rateButton = (Button) row.findViewById(R.id.rate_button); holder.currentPosition = position; row.setTag(holder); right above the click listener.
|
0

You are not setting real position to the Button.

Move your Button.setTag() line from inside the if to outside of the if-else condition where the text and other data is being set. So after the scroll or refresh, it should get the real position on every call of getView() like this:

public View getView(final int position, View convertView, ViewGroup parent)
{
    View row = convertView;
    CitrusListHolder holder = null;

    if(row == null)
    {
        //your implementation
    }
    else
    {
        //your implementation
    }

    CitrusList singleLine = data.get(position);
    //holder.txtTitle.setText(singleLine.title);
    rateButton.setTag(String.valueOf(position));  //<==== place it here, so it'll get the real/update position as tag, Convert it to String.
    return row;
}

and while getting it in onClick(). cast it to String then convert it to Integer like this:

int position = Integer.parseInt(v.getTag().toString());

Comments

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.